package com.nfc.lock.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nfc.lock.common.constant.Constants;
import com.nfc.lock.common.exception.BusinessException;
import com.nfc.lock.common.result.ResultCode;
import com.nfc.lock.dto.request.LoginRequest;
import com.nfc.lock.dto.request.UserAddRequest;
import com.nfc.lock.dto.response.LoginResponse;
import com.nfc.lock.dto.response.UserInfoVO;
import com.nfc.lock.entity.Region;
import com.nfc.lock.entity.User;
import com.nfc.lock.mapper.RegionMapper;
import com.nfc.lock.mapper.UserMapper;
import com.nfc.lock.security.JwtProperties;
import com.nfc.lock.security.JwtTokenProvider;
import com.nfc.lock.security.SecurityUtils;
import com.nfc.lock.service.IUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 用户Service实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private final UserMapper userMapper;
    private final RegionMapper regionMapper;
    private final PasswordEncoder passwordEncoder;
    private final JwtTokenProvider jwtTokenProvider;
    private final JwtProperties jwtProperties;

    @Override
    public LoginResponse login(LoginRequest request) {
        // 1. 查询用户
        User user = userMapper.selectByUsername(request.getUsername());
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_EXIST);
        }

        // 2. 验证密码
        if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
            throw new BusinessException(ResultCode.USERNAME_PASSWORD_ERROR);
        }

        // 3. 检查状态
        if (user.getStatus() != null && user.getStatus() == 0) {
            throw new BusinessException("用户已被禁用");
        }

        // 4. 生成Token
        String token = jwtTokenProvider.generateToken(user);

        // 5. 组装响应
        LoginResponse response = new LoginResponse();
        response.setToken(token);
        response.setExpiresIn(jwtProperties.getExpiration());
        response.setUserInfo(buildUserInfoVO(user));

        log.info("用户登录成功: {}", user.getUsername());
        return response;
    }

    @Override
    public UserInfoVO getCurrentUserInfo() {
        Long userId = SecurityUtils.getCurrentUserId();
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_EXIST);
        }
        return buildUserInfoVO(user);
    }

    @Override
    public IPage<UserInfoVO> getUserList(Integer pageNum, Integer pageSize, String realName,
                                         Integer roleType, Long regionId) {
        // 获取当前用户
        Long currentUserId = SecurityUtils.getCurrentUserId();
        User currentUser = userMapper.selectById(currentUserId);

        // 构建查询条件
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();

        // 非超级管理员只能查看下属区域的用户
        if (currentUser != null && currentUser.getRoleType() != null
                && !currentUser.getRoleType().equals(Constants.RoleType.SUPER_ADMIN)) {
            Region currentRegion = regionMapper.selectById(currentUser.getRegionId());
            if (currentRegion != null) {
                List<Long> regionIds = regionMapper.selectByLevelPathLike(currentRegion.getLevelPath())
                        .stream()
                        .map(Region::getRegionId)
                        .toList();
                if (!regionIds.isEmpty()) {
                    wrapper.in(User::getRegionId, regionIds);
                } else {
                    wrapper.eq(User::getRegionId, -1L);
                }
            }
        }

        // 其他条件
        if (realName != null && !realName.isEmpty()) {
            wrapper.like(User::getRealName, realName);
        }
        if (roleType != null) {
            wrapper.eq(User::getRoleType, roleType);
        }
        if (regionId != null) {
            wrapper.eq(User::getRegionId, regionId);
        }

        wrapper.orderByDesc(User::getCreateTime);

        // 分页查询
        Page<User> page = new Page<>(pageNum, pageSize);
        Page<User> userPage = userMapper.selectPage(page, wrapper);

        // 转换为VO
        Page<UserInfoVO> voPage = new Page<>();
        BeanUtils.copyProperties(userPage, voPage);
        voPage.setRecords(userPage.getRecords().stream()
                .map(this::buildUserInfoVO)
                .toList());

        return voPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addUser(UserAddRequest request) {
        // 1. 检查用户名是否存在
        if (userMapper.selectByUsername(request.getUsername()) != null) {
            throw new BusinessException(ResultCode.USERNAME_EXIST);
        }

        // 2. 检查权限
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (!checkPermission(currentUserId, request.getRegionId())) {
            throw new BusinessException(ResultCode.FORBIDDEN);
        }

        // 3. 创建用户
        User user = new User();
        BeanUtils.copyProperties(request, user);
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setStatus(1);
        user.setCreateBy(currentUserId);

        userMapper.insert(user);
        log.info("新增用户成功: {}", user.getUsername());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUser(Long userId, UserAddRequest request) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_EXIST);
        }

        // 检查权限
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (!checkPermission(currentUserId, user.getRegionId())) {
            throw new BusinessException(ResultCode.FORBIDDEN);
        }

        BeanUtils.copyProperties(request, user);
        // 如果修改了密码
        if (request.getPassword() != null && !request.getPassword().isEmpty()) {
            user.setPassword(passwordEncoder.encode(request.getPassword()));
        }

        userMapper.updateById(user);
        log.info("更新用户成功: {}", userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteUser(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_EXIST);
        }

        // 检查权限
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (!checkPermission(currentUserId, user.getRegionId())) {
            throw new BusinessException(ResultCode.FORBIDDEN);
        }

        userMapper.deleteById(userId);
        log.info("删除用户成功: {}", userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetPassword(Long userId, String newPassword) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_EXIST);
        }

        user.setPassword(passwordEncoder.encode(newPassword));
        userMapper.updateById(user);
        log.info("重置密码成功: {}", userId);
    }

    @Override
    public boolean checkPermission(Long userId, Long targetRegionId) {
        if (targetRegionId == null) {
            return false;
        }
        User user = userMapper.selectById(userId);
        if (user == null) {
            return false;
        }

        // 超级管理员有所有权限
        if (user.getRoleType() != null && user.getRoleType() == Constants.RoleType.SUPER_ADMIN) {
            return true;
        }

        // 使用人只能操作本区域
        if (user.getRoleType() != null && user.getRoleType() == Constants.RoleType.USER) {
            return targetRegionId.equals(user.getRegionId());
            }

        // 管理员检查层级关系
        Region userRegion = regionMapper.selectById(user.getRegionId());
        Region targetRegion = regionMapper.selectById(targetRegionId);

        if (userRegion == null || targetRegion == null) {
            return false;
        }

        // 目标区域的路径必须以用户区域的路径开头
        return targetRegion.getLevelPath() != null
                && targetRegion.getLevelPath().startsWith(userRegion.getLevelPath());
    }

    /**
     * 构建用户信息VO
     */
    private UserInfoVO buildUserInfoVO(User user) {
        UserInfoVO vo = new UserInfoVO();
        BeanUtils.copyProperties(user, vo);

        // 设置角色名称
        vo.setRoleName(getRoleName(user.getRoleType()));

        // 设置区域名称
        if (user.getRegionId() != null) {
            Region region = regionMapper.selectById(user.getRegionId());
            if (region != null) {
                vo.setRegionName(region.getRegionName());
            }
        }

        return vo;
    }

    /**
     * 获取角色名称
     */
    private String getRoleName(Integer roleType) {
        return switch (roleType) {
            case Constants.RoleType.SUPER_ADMIN -> "超级管理员";
            case Constants.RoleType.PROVINCE -> "省管理员";
            case Constants.RoleType.CITY -> "市管理员";
            case Constants.RoleType.COUNTY -> "县管理员";
            case Constants.RoleType.CENTER -> "城区供电中心管理员";
            case Constants.RoleType.STATION -> "供电所管理员";
            case Constants.RoleType.USER -> "使用人";
            default -> "未知";
        };
    }
}
